From 6a5586a416fb167dbfcf68270b708cdcf840c468 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Wed, 22 Jul 2015 10:56:56 -0400 Subject: [PATCH] gtk-demo: Add a filter model example This shows computed columns. --- demos/gtk-demo/Makefile.am | 1 + demos/gtk-demo/demo.gresource.xml | 1 + demos/gtk-demo/filtermodel.c | 160 ++++++++++++++++++++++++++++++ 3 files changed, 162 insertions(+) create mode 100644 demos/gtk-demo/filtermodel.c diff --git a/demos/gtk-demo/Makefile.am b/demos/gtk-demo/Makefile.am index ec54896a2c..f03f1c6873 100644 --- a/demos/gtk-demo/Makefile.am +++ b/demos/gtk-demo/Makefile.am @@ -25,6 +25,7 @@ demos_base = \ entry_completion.c \ event_axes.c \ expander.c \ + filtermodel.c \ font_features.c \ gestures.c \ glarea.c \ diff --git a/demos/gtk-demo/demo.gresource.xml b/demos/gtk-demo/demo.gresource.xml index 3c71240d46..c3dd82ce77 100644 --- a/demos/gtk-demo/demo.gresource.xml +++ b/demos/gtk-demo/demo.gresource.xml @@ -131,6 +131,7 @@ entry_completion.c event_axes.c expander.c + filtermodel.c flowbox.c font_features.c gestures.c diff --git a/demos/gtk-demo/filtermodel.c b/demos/gtk-demo/filtermodel.c new file mode 100644 index 0000000000..c2acea363b --- /dev/null +++ b/demos/gtk-demo/filtermodel.c @@ -0,0 +1,160 @@ +/* Tree View/Filter Model + * + * This example demonstrates how GtkTreeModelFilter can be used + * to compute columns that are not actually present in the underlying + * model. + */ + +#include + +enum { + WIDTH_COLUMN, + HEIGHT_COLUMN, + AREA_COLUMN, + SQUARE_COLUMN +}; + +static void +format_number (GtkTreeViewColumn *col, + GtkCellRenderer *cell, + GtkTreeModel *model, + GtkTreeIter *iter, + gpointer data) +{ + gint num; + gchar *text; + + gtk_tree_model_get (model, iter, GPOINTER_TO_INT (data), &num, -1); + text = g_strdup_printf ("%d", num); + g_object_set (cell, "text", text, NULL); + g_free (text); +} + +static void +filter_modify_func (GtkTreeModel *model, + GtkTreeIter *iter, + GValue *value, + gint column, + gpointer data) +{ + GtkTreeModelFilter *filter_model = GTK_TREE_MODEL_FILTER (model); + gint width, height; + GtkTreeModel *child_model; + GtkTreeIter child_iter; + + child_model = gtk_tree_model_filter_get_model (filter_model); + gtk_tree_model_filter_convert_iter_to_child_iter (filter_model, &child_iter, iter); + + gtk_tree_model_get (child_model, &child_iter, + WIDTH_COLUMN, &width, + HEIGHT_COLUMN, &height, + -1); + + switch (column) + { + case WIDTH_COLUMN: + g_value_set_int (value, width); + break; + case HEIGHT_COLUMN: + g_value_set_int (value, height); + break; + case AREA_COLUMN: + g_value_set_int (value, width * height); + break; + case SQUARE_COLUMN: + g_value_set_boolean (value, width == height); + break; + default: + g_assert_not_reached (); + } +} + +GtkWidget * +do_filtermodel (GtkWidget *do_widget) +{ + static GtkWidget *window; + GtkWidget *tree; + GtkListStore *store; + GtkTreeModel *model; + GtkTreeViewColumn *column; + GtkCellRenderer *cell; + GType types[4]; + + if (!window) + { + window = gtk_window_new (GTK_WINDOW_TOPLEVEL); + gtk_window_set_screen (GTK_WINDOW (window), + gtk_widget_get_screen (do_widget)); + gtk_window_set_title (GTK_WINDOW (window), "Filter Model"); + g_signal_connect (window, "destroy", + G_CALLBACK (gtk_widget_destroyed), &window); + + tree = gtk_tree_view_new (); + gtk_container_add (GTK_CONTAINER (window), tree); + + column = gtk_tree_view_column_new (); + gtk_tree_view_column_set_title (column, "Width"); + cell = gtk_cell_renderer_text_new (); + gtk_tree_view_column_pack_start (column, cell, FALSE); + gtk_tree_view_column_set_cell_data_func (column, cell, + format_number, GINT_TO_POINTER (WIDTH_COLUMN), NULL); + gtk_tree_view_append_column (GTK_TREE_VIEW (tree), column); + + column = gtk_tree_view_column_new (); + gtk_tree_view_column_set_title (column, "Height"); + cell = gtk_cell_renderer_text_new (); + gtk_tree_view_column_pack_start (column, cell, FALSE); + gtk_tree_view_column_set_cell_data_func (column, cell, + format_number, GINT_TO_POINTER (HEIGHT_COLUMN), NULL); + gtk_tree_view_append_column (GTK_TREE_VIEW (tree), column); + + column = gtk_tree_view_column_new (); + gtk_tree_view_column_set_title (column, "Area"); + cell = gtk_cell_renderer_text_new (); + gtk_tree_view_column_pack_start (column, cell, FALSE); + gtk_tree_view_column_set_cell_data_func (column, cell, + format_number, GINT_TO_POINTER (AREA_COLUMN), NULL); + gtk_tree_view_append_column (GTK_TREE_VIEW (tree), column); + + column = gtk_tree_view_column_new (); + gtk_tree_view_column_set_title (column, "Square"); + cell = gtk_cell_renderer_pixbuf_new (); + g_object_set (cell, "icon-name", "object-select-symbolic", NULL); + gtk_tree_view_column_pack_start (column, cell, FALSE); + gtk_tree_view_column_add_attribute (column, cell, "visible", SQUARE_COLUMN); + gtk_tree_view_append_column (GTK_TREE_VIEW (tree), column); + + store = gtk_list_store_new (2, G_TYPE_INT, G_TYPE_INT); + store = gtk_list_store_new (2, G_TYPE_INT, G_TYPE_INT); + gtk_list_store_insert_with_values (store, NULL, -1, + WIDTH_COLUMN, 10, + HEIGHT_COLUMN, 20, + -1); + gtk_list_store_insert_with_values (store, NULL, -1, + WIDTH_COLUMN, 5, + HEIGHT_COLUMN, 25, + -1); + gtk_list_store_insert_with_values (store, NULL, -1, + WIDTH_COLUMN, 15, + HEIGHT_COLUMN, 15, + -1); + + types[WIDTH_COLUMN] = G_TYPE_INT; + types[HEIGHT_COLUMN] = G_TYPE_INT; + types[AREA_COLUMN] = G_TYPE_INT; + types[SQUARE_COLUMN] = G_TYPE_BOOLEAN; + model = gtk_tree_model_filter_new (GTK_TREE_MODEL (store), NULL); + gtk_tree_model_filter_set_modify_func (GTK_TREE_MODEL_FILTER (model), + G_N_ELEMENTS (types), types, + filter_modify_func, NULL, NULL); + + gtk_tree_view_set_model (GTK_TREE_VIEW (tree), model); + } + + if (!gtk_widget_get_visible (window)) + gtk_widget_show_all (window); + else + gtk_widget_destroy (window); + + return window; +} -- 2.30.2